Skip to content

feat(cli): resolve issue workflow state by name on issues update#31

Merged
dubscode merged 3 commits into
mainfrom
feat/issue-22-state-by-name-resolver
May 28, 2026
Merged

feat(cli): resolve issue workflow state by name on issues update#31
dubscode merged 3 commits into
mainfrom
feat/issue-22-state-by-name-resolver

Conversation

@dubscode

@dubscode dubscode commented May 28, 2026

Copy link
Copy Markdown
Contributor

What shipped

  • A reusable resolveStateId module in @wiseiodev/linear-core that maps a state reference (a UUID or a human name) to a stateId for a team, with an optional preferred-type fallback reserved for later slices.
  • linear issues update ANN-1 --state "In Progress" now works with no --input required.
  • --input '{"state":"In Progress"}' and --input '{"stateName":"In Progress"}' resolve to the right stateId.
  • Resolution is scoped to the target issue's team (the issue is fetched to read its teamId); a raw stateId UUID still passes through unchanged.
  • Unknown/ambiguous state names fail with a typed error listing the team's valid states as name (type); state/stateName keys are stripped before the payload reaches GraphQL.
  • New listWorkflowStatesForTeam gateway method (server-side team filter) and a position field on WorkflowStateRecord.
  • Agent-facing guidance shipped with the feature: a "Set Issue State By Name" + "Common Mistakes" section in the bundled linear-cli skill, a setter-guidance block in issues update --help, a README example, and concrete state-by-name hints in the issue-triage and cycle-planning skills.

Dependencies collected

Dependency Value / status
External dependencies None detected — pure code/docs change in an existing CLI/SDK monorepo.

Files changed

 .reports/issue-22-qa.md                            | 130 ++++++
 .reports/issue-22.html                             | 444 +++++++++++++++++++++
 README.md                                          |   1 +
 assets/skills/cycle-planning/SKILL.md              |   7 +
 assets/skills/issue-triage/SKILL.md                |   7 +
 assets/skills/linear-cli/SKILL.md                  |  37 ++
 packages/cli/src/commands/input.ts                 |   8 +
 packages/cli/src/commands/issue-state.ts           |  76 ++++
 packages/cli/src/commands/resource.ts              |  11 +-
 packages/cli/src/help/resource-help.ts             |  12 +-
 packages/cli/src/index.ts                          |  19 +-
 packages/cli/tests/issue-state.test.ts             | 155 +++++++
 packages/linear-core/src/entities/linear-gateway.ts |  11 +
 packages/linear-core/src/entities/models.ts        |   1 +
 packages/linear-core/src/entities/state-resolver.ts |  94 +++++
 packages/linear-core/src/index.ts                  |   1 +
 packages/linear-core/tests/state-resolver.test.ts  |  85 ++++
 packages/skills-catalog/tests/skills-catalog.test.ts |  19 +
 18 files changed, 1111 insertions(+), 7 deletions(-)

Tests added

  • packages/linear-core/tests/state-resolver.test.ts — 8 Vitest cases (UUID passthrough, case-insensitive name match, team scoping, preferred-type fallback incl. position-less states, not-found, ambiguous).
  • packages/cli/tests/issue-state.test.ts — 10 Vitest cases (--state flag, state/stateName keys, explicit stateId untouched, empty stateId no longer pre-empts, padded UUID short-circuit, precedence, no-state passthrough, unknown name error).
  • packages/skills-catalog/tests/skills-catalog.test.ts — +1 case asserting the bundled skill documents state-by-name.

Quality gates

  • Lint / format — pnpm check:write (biome)
  • Typecheck — pnpm typecheck (turbo, 4 pkgs)
  • Unit tests — pnpm test (linear-core 58, cli 60, skills-catalog 7)
  • Build — pnpm build (turbo, 4 pkgs)
  • E2E — no E2E suite in this repo (N/A)

Adversarial review

  • Iterations: 2
  • Critical / Major: 0 / 0
  • Minor: 0
  • Nitpick: 0
  • Resolved or accepted findings:
    • Two round-1 "major" findings resolved by scope/PRD reasoning: (a) reusing the global --state as the setter on update is PRD-mandated ("no new flag required") — the update help now documents the setter usage; (b) issues bulk-update state-by-name is owned by sibling issue State-by-name on issues create + bulk-update #27 and is untouched/unregressed here.
    • Five minor/nitpick findings fixed in code: undefined position now sorts last in the type fallback; only a non-empty stateId pre-empts resolution; asString trims so padded UUIDs short-circuit; explanatory comments added for the UUID short-circuit and the 250-state page cap.
    • Round 2 confirmed all fixes correct, no regressions, zero remaining critical/major.

Self-QA

See QA fallback log for the per-acceptance-criterion verification trail (deterministic unit tests, a runtime demonstration against the built @wiseiodev/linear-core module, a CLI help smoke test, and the docs/hints surfaces verified via issues update --help). This is a terminal CLI / SDK change with no browser surface, so a Playwright video is not applicable.

Acceptance criteria

  • issues update <id> --state "<name>" sets the issue to the matching state
  • --input '{"stateName":"<name>"}' and --input '{"state":"<name>"}' resolve to a stateId
  • --input '{"stateId":"<uuid>"}' continues to work unchanged
  • Resolution is scoped to the target issue's team
  • Unknown/ambiguous name errors with the team's valid state names listed
  • state/stateName keys never reach GraphQL
  • Resolver unit tests cover UUID passthrough, name match, type fallback, not-found, ambiguous
  • issues update normalization is tested (flag + JSON-key paths, stateId untouched)
  • Docs/help/hints updated for the new capability (skill, CLI help, README, sibling skills)

Commits

d50dd61 docs(cli): document state-by-name across help, skill, and README
7d9c140 chore(report): add work report for issue #22
2328090 feat(cli): resolve issue workflow state by name on issues update

Linear

Refs: #22

dubscode added 2 commits May 27, 2026 23:14
Add a reusable workflow-state resolver in linear-core that maps a state
reference (UUID or human name) to a stateId for a team, and wire it into
`issues update` so agents can set state with `--state "In Progress"` or
`--input '{"state":"..."}'`/`'{"stateName":"..."}'`. Resolution is scoped
to the target issue's team; an explicit stateId UUID still passes through
unchanged; state/stateName keys are stripped before reaching GraphQL.
Unknown or ambiguous names error with the team's valid states listed.

Refs: #22
Copilot AI review requested due to automatic review settings May 28, 2026 06:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a reusable workflow-state name/UUID resolver in @wiseiodev/linear-core and wires it into linear issues update so an issue's state can be set by name via either the global --state flag or state/stateName keys inside --input. Resolution is scoped to the target issue's team, raw stateId UUIDs pass through unchanged, and unknown/ambiguous names produce typed errors that enumerate valid states.

Changes:

  • New resolveStateId + isWorkflowStateId core module with UUID short-circuit, case-insensitive name match, optional preferredType fallback (lowest position first, missing positions sort last), and listing-aware error messages.
  • New LinearGateway.listWorkflowStatesForTeam (server-side team.id.eq filter, single page of 250) and a new position field on WorkflowStateRecord.
  • CLI: new normalizeIssueUpdateStatePayload folds --state / state / stateName into stateId, strips name keys, and skips the issue fetch for UUID refs or explicit non-empty stateId; registerResourceCommand gains an opt-in allowEmptyInput for update so issues update --state … works without --input.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/linear-core/src/entities/state-resolver.ts New resolver module: UUID guard, name matching, preferred-type fallback, typed errors.
packages/linear-core/src/entities/linear-gateway.ts Adds listWorkflowStatesForTeam and maps the new position field.
packages/linear-core/src/entities/models.ts Adds optional position to WorkflowStateRecord.
packages/linear-core/src/index.ts Re-exports the new resolver module.
packages/linear-core/tests/state-resolver.test.ts 8 Vitest cases covering passthrough, scoping, fallback, not-found, ambiguity.
packages/cli/src/commands/issue-state.ts New normalizeIssueUpdateStatePayload + IssueStateGateway interface.
packages/cli/src/commands/input.ts New parseOptionalJsonInput that returns {} when no input provided.
packages/cli/src/commands/resource.ts Adds ResourceCommandOptions.update.allowEmptyInput and routes parsing accordingly.
packages/cli/src/index.ts Wires the normalizer into issues update and opts the command into empty input.
packages/cli/src/help/resource-help.ts Adds --state and state-key examples to issues update help.
packages/cli/tests/issue-state.test.ts 10 Vitest cases for flag/JSON key paths, stateId precedence, UUID short-circuit, errors.
.reports/issue-22.html, .reports/issue-22-qa.md Work/QA reports documenting verification.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Surface the new state-by-name capability where agents will see it: a
"Set Issue State By Name" section plus a "common mistakes -> correct
command" table in the bundled linear-cli skill, a setter-guidance block
in `issues update --help` (new optional notes on update help), a README
example, and concrete state-by-name hints in the issue-triage and
cycle-planning skills. Locked by a skills-catalog test assertion.

Refs: #22
@dubscode dubscode merged commit 6e22fba into main May 28, 2026
5 checks passed
@dubscode dubscode deleted the feat/issue-22-state-by-name-resolver branch May 28, 2026 14:55
github-actions Bot pushed a commit that referenced this pull request May 28, 2026
# [1.6.0-alpha.1](v1.5.0...v1.6.0-alpha.1) (2026-05-28)

### Features

* **cli:** resolve issue workflow state by name on issues update ([#31](#31)) ([6e22fba](6e22fba)), closes [#22](#22) [#22](#22)
github-actions Bot pushed a commit that referenced this pull request May 30, 2026
# [1.6.0](v1.5.0...v1.6.0) (2026-05-30)

### Features

* **cli:** resolve issue workflow state by name on issues update ([#31](#31)) ([6e22fba](6e22fba)), closes [#22](#22) [#22](#22)
* complete agent issue UX ([#32](#32)) ([9aacd90](9aacd90))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.6.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants